<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class jQuickForm_Captcha extends HTML_QuickForm2_Element_InputText {
    const SECRETIMAGE_OFFSET_LETTER = 2;
    const SECRETIMAGE_FONT_SIZE     = 20;       //размер шрифта
    const SECRETIMAGE_MAX_ANGLE     = 45;       //максимальный угол случайного поворота букв
    const SECRETIMAGE_NOISE         = 30;    //чем меньше параметр,  тем больше точек в шуме
    const SECRETIMAGE_PROPORTION    = 1;
    const SECRETIMAGE_FONT_NAME     = 'tahoma.ttf';


    //цвета шума
    public $colors = array(0xFF0000,
    0xD56C56,
    0x0000FF,
    0xFFFF00,
    0x00FFFF,
    0xFF00FF);

    public $captcha_url = '/captcha.php';

    public function render(HTML_QuickForm2_Renderer $renderer){
//        $renderer = new HTML_QuickForm2_Renderer_Default();
        jQuickForm::css()->addCssInline('
        .jqf_captcha img {
            float:right;
            cursor:pointer;
        }
        .jqf_captcha span.jqf_error {
            padding-right:10px;
        }
        ');
        jQuickForm::js()->addJsOnload('
        jQuery("#captcha-'.$this->getId().'").click(function(){
            jQuery(this).attr("src","'.$this->captcha_url.'?"+Math.random());
        });
        ');
        $renderer->setTemplateForId($this->getId(),
        '
<div class="jqf_captcha jqf_row<qf:error> jqf_error</qf:error>">
    <img id="captcha-{id}" title="Кликните для перегенерации" alt="Кликните для перегенерации" src="'.$this->captcha_url.'" />
    <label for="{id}" class="jqf_element"><qf:required><span class="required">* </span></qf:required>{label}</label>
    <span class="jqf_error" id="jqferr-{id}"><qf:error>{error}</qf:error></span>
    <div class="jqf_element">
        {element}
        {comment}
        <div class="jqf_comment">Если не понятна надпись - кликните на картинку для перегенерации</div>
    </div>
</div>
        '
        );
        return parent::render($renderer);
    }

    function jqf_create_img($string=''){
        $font = dirname(__FILE__).'/fonts/'.self::SECRETIMAGE_FONT_NAME;
        if(!$string) $string = '0123456789';
        if(!$string) $string = 'bad';

        //###################################################################
        //  картинка с шумом
        //###################################################################
        //получим координаты самой широкой буквы
        $coord = imagettfbbox(self::SECRETIMAGE_FONT_SIZE,0,$font,'W');
        //рассчитаем высоту картинки
        $img_height = ($coord[3] - $coord[1]+self::SECRETIMAGE_OFFSET_LETTER*2);
        $img_height = self::SECRETIMAGE_FONT_SIZE*2;
        //рассчитаем ширину картинки
        $img_width = strlen($string)*($coord[2] - $coord[0] + self::SECRETIMAGE_OFFSET_LETTER*2)+20;

        $letter_width = ($coord[2] - $coord[0] + self::SECRETIMAGE_OFFSET_LETTER*2);
        $letter_heigh = ($coord[2] - $coord[0] + self::SECRETIMAGE_OFFSET_LETTER*2);
        //создадим основную картинку
        $image = imagecreatetruecolor($img_width, $img_height);


        //###################################################################
        //  картинка с текстом
        //###################################################################
        //рассчитаем высоту картинки
        $temp_height = intval($img_height/self::SECRETIMAGE_PROPORTION);
        //рассчитаем ширину картинки
        $temp_width  = intval($img_width/self::SECRETIMAGE_PROPORTION);
        //создадим картинку с текстом
        $temp = imagecreatetruecolor($temp_width, $temp_height);
        //закрасим ее фон белым
        $background_color = imagecolorallocate ($temp, 255, 255, 255);
        imagefill($temp, 0, 0, $background_color);
        $text_color = imagecolorallocate ($temp, 30,30,30);//black text

        //###################################################################
        //  пишем текст
        //###################################################################
        for ($x = 0; $x < strlen($string); $x++) {
            //генерация угла поворота
            srand();
            $angle = rand(-self::SECRETIMAGE_MAX_ANGLE,self::SECRETIMAGE_MAX_ANGLE);
            //расчет координат...
            $coord = imagettfbbox(intval(self::SECRETIMAGE_FONT_SIZE/self::SECRETIMAGE_PROPORTION),0,$font,$string[$x]);
            $text_x = intval($letter_width*$x/self::SECRETIMAGE_PROPORTION)  +  intval(($letter_width - $coord[2] + $coord[0])/self::SECRETIMAGE_PROPORTION);
            $text_y = intval(($letter_heigh - $coord[3] + $coord[1])/self::SECRETIMAGE_PROPORTION);
            imagettftext( $temp,
            intval(self::SECRETIMAGE_FONT_SIZE/self::SECRETIMAGE_PROPORTION),
            $angle,
            $text_x,
            $text_y,
            0,
            $font,
            $string[$x]);
        }


        imagecopyresized($image, $temp, 0, 0, 0, 0, $img_width, $img_height, $temp_width, $temp_height);
        imagedestroy($temp);
        for ($x = 0; $x <= $img_height*2; $x += 8){
            imageline($image, 0, $x, $img_width, $x-20, $text_color);
        }

        for ($x = 0; $x <= $img_width; $x += 20){
            imageline($image, $x, 0, $x+20, $img_height, $text_color);
        }

        $pixels = $img_width * $img_height / self::SECRETIMAGE_NOISE;
        for($i = 0; $i < $pixels; $i++){
            imagesetpixel($image, rand(0, $img_width), rand(0, $img_height), 0);
        }

        // get multipliers for waves
        $wavenum = 5;
        $wavemultiplier = ($wavenum * 360) / $img_width;

        // cosine wave
        $curX = 0;
        $curY = $img_height;
        for($pt = 0; $pt < $img_width; $pt++){
            $newX = $curX + 1;
            $newY = ($img_height/2) + (cos(deg2rad($newX * $wavemultiplier)) * ($img_height/2));
            ImageLine($image, $curX, $curY, $newX, $newY, $text_color);
            $curX = $newX;
            $curY = $newY;
        }

        // sine wave
        $curX = 0;
        $curY = 0;
        for($pt = 0; $pt < $img_width; $pt++){
            $newX = $curX + 1;
            $newY = ($img_height/2) + (sin(deg2rad($newX * $wavemultiplier - 90)) * ($img_height/2));
            ImageLine($image, $curX, $curY, $newX, $newY, $text_color);
            $curX = $newX;
            $curY = $newY;
        }

        if (function_exists('imagejpeg')) {
            header('Content-Type: image/jpeg');
            @@imagejpeg($image);
            imagedestroy($image);
        } else {
            if (function_exists('imagepng')) {
                header('Content-Type: image/png');
                @@imagepng($image);
                imagedestroy($image);
            }
            return false;
        }
        exit;
    }


    static function jqfMakeCode($force=false){
        if( (!isset($_SESSION['reg_img'])) || $force) {
            $reg_img = array();
            $max  = rand(50,100);
            $min  = rand(49,1);
            switch (rand(0,1)){
                //вычитание
                case 0:
                    $reg_img['text']     = sprintf('%s-%s=', $max, $min);
                    $reg_img['result']   = $max-$min;
                    break;

                    //сложение
                default:
                    $reg_img['text']     = sprintf('%s+%s=', $max, $min);
                    $reg_img['result']   = $max+$min;
            }
            $_SESSION['reg_img'] = $reg_img;
        }
    }

    static function validateCaptcha($value){
        return ($_SESSION['captcha_code']==$value);
    }
}
?>